package com.dba.example.gwt.client.views.impl;

import java.util.HashMap;
import java.util.Map;

import com.dba.example.gwt.client.beans.Company;
import com.dba.example.gwt.client.beans.Page;
import com.dba.example.gwt.client.places.CompanyEditPlace;
import com.dba.example.gwt.client.views.CompanyListView;
import com.google.gwt.cell.client.ClickableTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.Range;

public class CompanyListViewImpl extends Composite implements CompanyListView {
	
	private static final int ROWS_PER_PAGE = 20;

	private Presenter presenter;

	interface DefaultUiBinder extends UiBinder<Widget, CompanyListViewImpl> {
	}

	private static DefaultUiBinder uiBinder = GWT.create(DefaultUiBinder.class);

	private class CompanyDataProvider extends AsyncDataProvider<Company> {
		@Override
		protected void onRangeChanged(HasData<Company> display) {
			final Range range = display.getVisibleRange();
			
			if (presenter != null) {
				String sortColumn = "name";
				String sortDirection = "ASC";
				
				if (table.getColumnSortList().size() > 0) {
					sortColumn = columnDataName.get(table.getColumnSortList().get(0).getColumn());
					
					if (!table.getColumnSortList().get(0).isAscending()) {
						sortDirection = "DESC";
					}
				}
				
				presenter.getPage(range.getStart(), ROWS_PER_PAGE, sortColumn, sortDirection, searchText.getValue());
			}
		}
	}

	@UiField
	TextBox searchText;
	
	@UiField
	Button search;
	
	@UiField(provided = true)
	DataGrid<Company> table;

	@UiField(provided = true)
	SimplePager pager;
	
	private Column<?, ?> defaultColumn;

	private CompanyDataProvider dataProvider = new CompanyDataProvider();
	
	private Map<Column<?,?>, String> columnDataName = new HashMap<Column<?,?>, String>();;

	public CompanyListViewImpl() {
		initWidgets();

		initWidget(uiBinder.createAndBindUi(this));
	}

	public void setPresenter(Presenter presenter) {
		this.presenter = presenter;
	}

	public void initWidgets() {
		table = new DataGrid<Company>(20);

		table.setEmptyTableWidget(new Label("No Data"));
		table.setHeight("500px");
		table.setWidth("650px");

		Column<Company, String> nameColumn = new Column<Company, String>(
				new TextCell()) {
			@Override
			public String getValue(Company object) {
				return object.getName();
			}
		};
		table.addColumn(nameColumn, "Name");
		table.setColumnWidth(nameColumn, "300px");
		nameColumn.setSortable(true);
		columnDataName.put(nameColumn, "name");

		Column<Company, String> lastUpdatedColumn = new Column<Company, String>(new TextCell()) {
			@Override
			public String getValue(Company object) {
				return object.getLastUpdated();
			}
		};
		table.addColumn(lastUpdatedColumn, "Last Updated");
		table.setColumnWidth(lastUpdatedColumn, "150px");
		lastUpdatedColumn.setSortable(true);
		columnDataName.put(lastUpdatedColumn, "lastUpdated");
		
		Column<Company, String> editColumn = new Column<Company, String>(
				new ClickableTextCell()) {
			@Override
			public String getValue(Company object) {
				return "edit";
			}
		};
		editColumn.setFieldUpdater(new FieldUpdater<Company, String>() {
			@Override
			public void update(int index, Company company, String value) {
				presenter.goTo(new CompanyEditPlace(company.getId()));
			}
		});
		table.addColumn(editColumn, "");
		table.setColumnWidth(editColumn, "100px");
		editColumn.setHorizontalAlignment(Column.ALIGN_CENTER);

		pager = new SimplePager(SimplePager.TextLocation.CENTER);
		pager.setDisplay(table);

		dataProvider.addDataDisplay(table);
		
		defaultColumn = nameColumn;
		
		ColumnSortEvent.AsyncHandler sortHandler = new ColumnSortEvent.AsyncHandler(table);
		table.addColumnSortHandler(sortHandler);
	}

	public void reset() {
		searchText.setValue("");
		search();
	}
	
	@Override
	public void setPage(Page<Company> page) {
		dataProvider.updateRowCount(page.getTotalRows(), true);
		dataProvider.updateRowData(page.getDataOffset(), page.getData());
	}
	
	@UiHandler("search")
	void searchClicked(ClickEvent event) {
		search();
	}

	@UiHandler("searchText")
	void searchTextKeyUp(KeyUpEvent event) {
		if(event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
			search();
		}
	}
	
	private void search() {
		table.getColumnSortList().clear();
		table.getColumnSortList().push(defaultColumn);
		table.setVisibleRange(0, ROWS_PER_PAGE);
		
		presenter.getPage(0, ROWS_PER_PAGE, columnDataName.get(defaultColumn), "ASC", searchText.getValue());
	}

}
